package com.lijin.batchsys.framework.control;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionException;
import org.springframework.util.Assert;

import com.lijin.batchsys.framework.common.ApplicationContextHolder;
import com.lijin.batchsys.framework.common.BatchSysException;
import com.lijin.batchsys.framework.common.IBatchLogger;
import com.lijin.batchsys.framework.dao.model.JobInfo;
import com.lijin.batchsys.framework.dao.model.StepInfo;

public abstract class BatchSysAbstractJob implements IBatchSysJob {

	private static final Logger logger = Logger.getLogger(BatchSysAbstractJob.class);

	protected JobInfo jobInfo;
	protected List<BatchSysStep> steps = new ArrayList<BatchSysStep>();
	protected List<StepInfo> errSteps = new ArrayList<StepInfo>();

	public BatchSysAbstractJob(JobInfo jobInfo) {
		this.jobInfo = jobInfo;
	}
	
	/**
	 * 执行Job模板方法
	 */
	@Override
	public void execute(BatchExecContext batchCtx) {
		String jobSummary = "任务" + jobInfo.getSummary();
		if (steps.size() == 0) {
			throw new BatchSysException(jobSummary + "没有可执行的步骤");
		}
		try {
			logger.info(jobSummary + "执行开始...");
			// 执行该任务
			doExecute(batchCtx);
			logger.info(jobSummary + "执行完成...");
		} catch (Exception e) {
			logger.error(jobSummary + "执行出错...", e);
			throw new BatchSysException(jobSummary + "执行出错...", e);
		}
	}

	/**
	 * 各个子类自己实现
	 * 
	 * @param execution
	 * @throws JobExecutionException
	 */
	abstract protected void doExecute(BatchExecContext batchCtx);

	/**
	 * 执行单个步骤
	 * @param step
	 * @param batchCtx
	 */
	protected final void handleStep(BatchSysStep step, BatchExecContext batchCtx) {
		IBatchLogger batchLogger = ApplicationContextHolder.getBean("batchLogger");
		StepExecContext stepCtx = new StepExecContext(batchCtx, step.getStepInfo(), batchLogger);
		stepCtx.logContext();
		step.execute(stepCtx);
	}

	/**
	 * 添加一个任务
	 * 
	 * @param step
	 */
	@Override
	public void addStep(BatchSysStep step) {
		Assert.notNull(steps, "步骤未初始化");
		steps.add(step);
	}
	
	protected void addErrStep(StepInfo step) {
		errSteps.add(step);
	}

	public void setSteps(List<BatchSysStep> steps) {
		this.steps = steps;
	}

	public JobInfo getJobInfo() {
		return jobInfo;
	}

}
